package com.zaofan.mobile.controller;

import com.alipay.util.AlipayNotify;
import com.zaofan.bean.Account;
import com.zaofan.bean.AccountLog;
import com.zaofan.bean.Error;
import com.zaofan.bean.Recharge;
import com.zaofan.cache.CacheManage;
import com.zaofan.constant.StateConstant;
import com.zaofan.constant.TypeConstant;
import com.zaofan.service.AccountLogService;
import com.zaofan.service.AccountService;
import com.zaofan.service.ErrorService;
import com.zaofan.service.RechargeService;
import com.zaofan.utils.C3p0DataSourceUtils;
import com.zaofan.utils.JPushUtils;
import com.zaofan.utils.SqlBuilderUtils;

import org.apache.commons.dbutils.QueryRunner;

import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/alipay_recharge_notify")
public class AlipayRechargeController extends HttpServlet {

	private static final long serialVersionUID = 5035453965360402957L;

	private RechargeService rechargeService = new RechargeService();
	private AccountService accountService = new AccountService();
	private AccountLogService accountLogService = new AccountLogService();
	private ErrorService errorService = new ErrorService();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
			params.put(name, valueStr);
		}

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号

		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

		// 支付宝交易号

		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");
		BigDecimal price = new BigDecimal(total_fee);

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		System.err.println("out_trade_no = " + out_trade_no + ",trade_no= " + trade_no + ",trade_status= "
				+ trade_status + ",total_fee = " + total_fee + ",price= " + price + "");
		if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			// 请在这里加上商户的业务逻辑程序代码

			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			System.err.println("verify success");
			if (trade_status.equals("TRADE_FINISHED")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				// 如果有做过处理，不执行商户的业务程序

				// 注意：
				// 退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
			} else if (trade_status.equals("TRADE_SUCCESS")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				// 如果有做过处理，不执行商户的业务程序

				// 注意：
				// 付款完成后，支付宝系统发送该交易状态通知
				System.err.println("TRADE_FINISHED");
				Recharge recharge = rechargeService.findByRechargeNo(out_trade_no);
				if (recharge == null) {
					Error error = new Error();
					error.setAddTime(new Date());
					error.setError("支付宝支付出现问题,支付宝订单:" + out_trade_no + ",无法匹配不到系统的充值信息");
					error.setOrderNo(out_trade_no);
					errorService.add(error);
				} else {
					if (recharge.getPayState() == 2) {
						response.getWriter().println("success"); // 请不要修改或删除
						return;
					}
					Connection connection = C3p0DataSourceUtils.getConnection();
					try {
						connection.setAutoCommit(false);
						// 更新订单状态
						String sql = "update " + Recharge.class.getSimpleName().toLowerCase() + " set payState = "
								+ StateConstant.ORDER_PAY_STATE_PAY + ",state = " + StateConstant.ORDER_STATE_PAY
								+ ",payType='支付宝支付' where rechargeNo = '" + recharge.getRechargeNo() + "'";
						QueryRunner runner = new QueryRunner();
						runner.update(connection, sql);
						// 增加账户记录
						Account account = accountService.findById(recharge.getAccountId());
						if (account == null) {
							try {
								connection.rollback();
							} catch (SQLException e1) {
								e1.printStackTrace();
							}
							Error error = new Error();
							error.setAddTime(new Date());
							error.setError("支付宝支付出现问题,支付宝订单:" + out_trade_no + ",无法匹配不到系统的用户信息");
							error.setOrderNo(recharge.getRechargeNo());
							errorService.add(error);
						} else {
							AccountLog log = new AccountLog();
							log.setAccountId(account.getId());
							log.setAccountMobile(account.getMobile());
							log.setAddTime(new Date());
							log.setAfterMoney(account.getMoney().add(price));
							log.setBeforeMoney(account.getMoney());
							log.setMoney(recharge.getMoney());
							log.setType(TypeConstant.log_type_rechage_alipay);
							sql = SqlBuilderUtils.builderInsertSql(AccountLog.class, log);
							runner.update(connection, sql);
							account.setMoney(account.getMoney().add(price));
							// 活动判断
							if (isInActivity(recharge.getCityId())) {
//								BigDecimal free = price.divide(new BigDecimal(100)).setScale(
//										0,BigDecimal.ROUND_FLOOR).multiply(new BigDecimal(100));
								BigDecimal free = new BigDecimal(0);
								if(price.compareTo(new BigDecimal(500))>=0){
									 free = new BigDecimal(150);
								}else if (price.compareTo(new BigDecimal(300))>=0){
									 free = new BigDecimal(80);
								}else if (price.compareTo(new BigDecimal(200))>=0){
									 free = new BigDecimal(50);

								}else if (price.compareTo(new BigDecimal(100))>=0){
									 free = new BigDecimal(20);
								}

								if (free.compareTo(new BigDecimal(0)) > 0) {
									log = new AccountLog();
									log.setAccountId(account.getId());
									log.setAccountMobile(account.getMobile());
									log.setAddTime(new Date());
									log.setAfterMoney(account.getMoney().add(free));
									log.setBeforeMoney(account.getMoney());
									log.setMoney(free);
									log.setType(TypeConstant.log_type_rechage_return_activity);
									sql = SqlBuilderUtils.builderInsertSql(AccountLog.class, log);
									runner.update(connection, sql);
									account.setMoney(account.getMoney().add(free));
								}
							};


							sql = SqlBuilderUtils.builderUpdateSql(Account.class, account);
							runner.update(connection, sql);
						}
						connection.commit();
						JPushUtils.sendRechargeSuccess(recharge, account);
					} catch (Exception e) {
						try {
							connection.rollback();
						} catch (SQLException e1) {
							e1.printStackTrace();
						}
						e.printStackTrace();
						return;
					} finally {
						try {
							connection.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
				}

			}
			// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
			response.getWriter().println("success"); // 请不要修改或删除
		} else

		{// 验证失败
			System.err.println("verify fail");
			response.getWriter().println("fail");
		}

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	public boolean isInActivity(Integer cityId) {
		if (CacheManage.setting.getRechargeReturn() == 1) {
			if (cityId == 0 || cityId == 2 || cityId ==1) {
				return true;
			}
		}
		return false;
	}
}
